package com.pesilo.mvc.view.component.module.commonModule
{	
	import com.pesilo.event.PesiloEvent;
	import com.pesilo.mvc.model.vo.VideoVO;
	import com.pesilo.util.Logger;
	
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.MouseEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	
	import org.osmf.containers.MediaContainer;
	import org.osmf.elements.VideoElement;
	import org.osmf.events.LoadEvent;
	import org.osmf.events.LoaderEvent;
	import org.osmf.events.MediaElementEvent;
	import org.osmf.events.MediaErrorEvent;
	import org.osmf.events.MediaPlayerCapabilityChangeEvent;
	import org.osmf.events.MediaPlayerStateChangeEvent;
	import org.osmf.events.TimeEvent;
	import org.osmf.events.TimelineMetadataEvent;
	import org.osmf.layout.LayoutMetadata;
	import org.osmf.media.DefaultMediaFactory;
	import org.osmf.media.MediaElement;
	import org.osmf.media.MediaFactory;
	import org.osmf.media.MediaPlayer;
	import org.osmf.media.MediaPlayerState;
	import org.osmf.media.URLResource;
	import org.osmf.metadata.CuePoint;
	import org.osmf.metadata.CuePointType;
	import org.osmf.metadata.Metadata;
	import org.osmf.metadata.TimelineMetadata;
	import org.osmf.net.NetStreamCodes;

	public class VideoComponent extends Sprite
	{

		private var errorTime:int=0;
		
		private var keyList:Array=[];
		private var videoContainer:Sprite;
		private var _mediaFactory:MediaFactory;
		private var _mediaElement:MediaElement;
		private var _mediaPlayer:MediaPlayer;
		private var _mediaContainer:MediaContainer;
		private var _layout:LayoutMetadata;
		private var dynamicTimelineMetadata:TimelineMetadata;

		public var curVolum:Number=.6;
		private var dataLoader:URLLoader;
		private var duarationTime:Number;
		private var vo:VideoVO;
		
		private var curPosTime:Number=0;

		private var isNewVideo:Boolean=true;
		private var isStop:Boolean=false;

		public function VideoComponent()
		{
			this.addEventListener(Event.ADDED_TO_STAGE, __addToStageHandle);
		}

		private function __addToStageHandle(e:Event):void
		{
			this.removeEventListener(Event.ADDED_TO_STAGE, __addToStageHandle);
			initUI();
		}

		private function initUI():void
		{
			videoContainer=new Sprite();
			this.addChild(videoContainer);
			_setupOSMF();
		}
		
		

		/**
		 * 根据vo播放视频
		 * @param vo
		 *
		 */
		public function playVideoByVO(vo:VideoVO):void
		{
			errorTime=0;
			//initMediaPlayerEvent(true);
			isNewVideo=true;
			curPosTime=0;
			this.vo=vo;

			//如果存在打点信息路径，则导入打点信息
			/*if (vo.pos)
			{
				dataLoader=new URLLoader();
				dataLoader.addEventListener(IOErrorEvent.IO_ERROR, function():void
				{
					Logger.logError("error")
				});
				dataLoader.addEventListener(Event.COMPLETE, __posDataLoadCompleteHandle);
				dataLoader.load(new URLRequest(vo.pos));
			}*/
			resetWH(vo.width, vo.height);

			_playVideo(vo.url, vo.list);
		}

		/**
		 * 打点信息处理
		 * @param e
		 *
		 */
		/*private function __posDataLoadCompleteHandle(e:Event):void
		{
			var xml:XML=XML(e.currentTarget.data);
			var posList:XMLList=xml.keyframes.filepositions.pos;
			var timeList:XMLList=xml.keyframes.times.time;
			keyList=[];
			for (var i:uint=0; i < posList.length(); i++)
			{
				var obj:Object={"time": timeList[i], "pos": posList[i]};
				keyList.push(obj);
			}
			duarationTime=xml.duration;
		}*/

		/**
		 * 从头开始播放视频
		 * @param videoToPlay 视频URL
		 * @param list 时间点信息列表
		 *
		 */
		private function _playVideo(videoToPlay:String, list:Array=null):void
		{
			cleanUpVideo();
			_mediaElement=_mediaFactory.createMediaElement(new URLResource(videoToPlay));
			_mediaElement.addMetadata(LayoutMetadata.LAYOUT_NAMESPACE, _layout);
			_mediaElement.addEventListener(MediaElementEvent.METADATA_ADD, onMetadataAdd);
			VideoElement(_mediaElement).smoothing=true;

			_mediaPlayer.media=_mediaElement;


			setVolum(curVolum);
			_mediaContainer.addMediaElement(_mediaElement);

			dynamicTimelineMetadata=new TimelineMetadata(_mediaElement);
			if (list)
			{
				for (var i:uint=0; i < list.length; i++)
				{
					addCuePoint(list[i].time, String(list[i].id));
				}
			}
		}

		/**
		 * 当metadata添加
		 * @param e
		 *
		 */
		private function onMetadataAdd(e:MediaElementEvent):void
		{
			trace(e);
		}

		/**
		 * 每个时间点对应的点信息
		 * @param t
		 * @return
		 *
		 */
		private function getPostion(t:Number):Number
		{
			for (var i:int=(keyList.length - 1); i > -1; i--)
			{
				if (t > keyList[i]["time"])
				{
					return keyList[i]["pos"];
				}
			}
			return 1;
		}

		/**
		 * 切换音量
		 *
		 */
		public function toggleVolum():void
		{
			if (_mediaPlayer.volume != 0)
			{
				setVolum(0, false)
			}
			else
			{
				setVolum(curVolum, false);
			}
		}

		/**
		 * 获取音量
		 */
		public function getVolum():Number{
			return _mediaPlayer.volume;
		}
		
		/**
		 * 设置音量
		 * @param n
		 * @param b
		 *
		 */
		public function setVolum(n:Number, b:Boolean=true):void
		{
			_mediaPlayer.volume=n;
			if (b)
				curVolum=n;
			this.dispatchEvent(new PesiloEvent(PesiloEvent.VIDEO_SET_VOLUM_EVENT, n));
		}

		/**
		 * 重置高宽
		 * @param w
		 * @param h
		 * @param isResume
		 *
		 */
		public function resetWH(w:Number, h:Number, isResume:Boolean=false):void
		{
			if (isResume)
			{
				_layout.width=vo.width;
				_layout.height=vo.height;
				/*_layout.x=-vo.width / 2;
				_layout.y=-vo.height / 2;*/
				_layout.x=0;
				_layout.y=0;
			}
			else
			{
				_layout.width=w;
				_layout.height=h;
				/*_layout.x=-w / 2;
				_layout.y=-h / 2;*/
				_layout.x=0;
				_layout.y=0;
			}
		}

		/**
		 * 加入时间监听点
		 * @param time
		 * @param name
		 *
		 */
		public function addCuePoint(time:Number, name:String):void
		{
			var cuePoint:CuePoint=new CuePoint(CuePointType.ACTIONSCRIPT, time, name, null);

			dynamicTimelineMetadata.addMarker(cuePoint);

			dynamicTimelineMetadata.addEventListener(TimelineMetadataEvent.MARKER_TIME_REACHED, onCuePoint);

		}

		/**
		 * 当监听点被触发
		 * @param event
		 *
		 */
		private function onCuePoint(event:TimelineMetadataEvent):void
		{
			var cuePoint:CuePoint=event.marker as CuePoint;
			this.dispatchEvent(new PesiloEvent(PesiloEvent.VIDEO_CUEPOINT_UPDATE_EVENT, {"id": cuePoint.name}));
			Logger.logInfo("Cue Point at " + cuePoint.time, " and name is " + cuePoint.name);
		}


		/**
		 * 播放
		 *
		 */
		public function play():void
		{
			if(isStop){
				isStop=false;
				seekVideo(0);
			}else
			_mediaPlayer.play();
		}

		/**
		 * 暂停
		 *
		 */
		public function pause():void
		{
			_mediaPlayer.pause();
		}

		/*public function seekVideoByNumber(n:Number):void
		{

			//_mediaPlayer.seek(n);
			if (keyList.length == 0)
			{
				if (_mediaPlayer.canSeekTo(n))
					_mediaPlayer.seek(n);
			}
			else
			{
				var start:Number=getPostion(n);
				_playUrl(this.url + "?start=" + start);
			}
		}*/

		/**
		 * 搜索打点时间点
		 * @param seekTo
		 *
		 */
		public function seekVideo(seekTo:Number):void
		{
			if (keyList.length == 0)
			{
				if (_mediaPlayer.canSeekTo(seekTo * _mediaPlayer.duration))
					_mediaPlayer.seek(seekTo * _mediaPlayer.duration);
			}
			else
			{
//				var start:Number=getPostion(seekTo * duarationTime);
				var start:Number=Math.ceil(100*(seekTo * duarationTime))/100;
				curPosTime=start;
				trace(vo.url + "?start=" + start);
				_playVideo(vo.url + "?start=" + start, vo.list);
				
				this.dispatchEvent(new PesiloEvent(PesiloEvent.VIDEO_FILE_SEEK_EVENT,{start:start,url:vo.url}));
				
			}
			//ApplicationFacade.getInstance().sendNotification(ApplicationFacade.EVENT_VIDEO_SEEK, seekTo * duarationTime);
		}



		/**
		 * 设置视频
		 *
		 */
		private function _setupOSMF():void
		{
			_mediaPlayer=new MediaPlayer();
			_mediaPlayer.autoRewind=false;

			_mediaFactory=new DefaultMediaFactory();
			_layout=new LayoutMetadata();
			/*_layout.width=vo.width;
			_layout.height=vo.height;*/
			/*_layout.x =-vo.width/2;
			_layout.y = -vo.height/2; */

			_mediaContainer=new MediaContainer();
			videoContainer.addChild(_mediaContainer);

			initMediaPlayerEvent(true);
		}

		private function initMediaPlayerEvent(b:Boolean=true):void
		{
			if (b)
			{
				_mediaPlayer.addEventListener(TimeEvent.CURRENT_TIME_CHANGE, _onCurrentTimeChange, false, 0, true);
				_mediaPlayer.addEventListener(TimeEvent.COMPLETE, _onComplete, false, 0, true);
				_mediaPlayer.addEventListener(MediaPlayerCapabilityChangeEvent.CAN_LOAD_CHANGE, _onCanLoadChange, false, 0, true);
				_mediaPlayer.addEventListener(MediaPlayerCapabilityChangeEvent.CAN_PLAY_CHANGE, _onCanPlayChange, false, 0, true);
				_mediaPlayer.addEventListener(MediaPlayerCapabilityChangeEvent.CAN_SEEK_CHANGE, _onCanSeekChange, false, 0, true);
				_mediaPlayer.addEventListener(MediaErrorEvent.MEDIA_ERROR, _onMediaError, false, 0, true);
				_mediaPlayer.addEventListener(MediaPlayerStateChangeEvent.MEDIA_PLAYER_STATE_CHANGE, _onMediaPlayerStateChange, false, 0, true);
				
				_mediaPlayer.addEventListener(LoadEvent.BYTES_LOADED_CHANGE,_bytesLoadedChangeHandle);
				_mediaPlayer.addEventListener(LoadEvent.BYTES_TOTAL_CHANGE,__bytesTotalChangeHandle);
			}
			else
			{
				_mediaPlayer.removeEventListener(TimeEvent.CURRENT_TIME_CHANGE, _onCurrentTimeChange);
				_mediaPlayer.removeEventListener(TimeEvent.COMPLETE, _onComplete);
				_mediaPlayer.removeEventListener(MediaPlayerCapabilityChangeEvent.CAN_LOAD_CHANGE, _onCanLoadChange);
				_mediaPlayer.removeEventListener(MediaPlayerCapabilityChangeEvent.CAN_PLAY_CHANGE, _onCanPlayChange);
				_mediaPlayer.removeEventListener(MediaPlayerCapabilityChangeEvent.CAN_SEEK_CHANGE, _onCanSeekChange);
				_mediaPlayer.removeEventListener(MediaErrorEvent.MEDIA_ERROR, _onMediaError);
				_mediaPlayer.removeEventListener(MediaPlayerStateChangeEvent.MEDIA_PLAYER_STATE_CHANGE, _onMediaPlayerStateChange);

			}
		}
		
		private var bytesTotal:int;
		protected function __bytesTotalChangeHandle(e:LoadEvent):void
		{
			trace("__bytesTotal:"+e.bytes);
			bytesTotal=e.bytes;
			
//			this.dispatchEvent(new VirplatEvent(VirplatEvent.VIDEO_TIME_UPDATE_EVENT, {"time": curTime, "duration": tTime}));
		}
		
		private var bytesLoaded:int;
		protected function _bytesLoadedChangeHandle(e:LoadEvent):void
		{
			bytesLoaded=e.bytes;
			var percent:Number=bytesLoaded/bytesTotal;
			this.dispatchEvent(new PesiloEvent(PesiloEvent.VIDEO_BYTES_LOADING_EVENT,percent));
		}
		
		/**
		 * 清理视频
		 *
		 */
		public function cleanUpVideo():void
		{
			//isNewVideo=true;
			//initMediaPlayerEvent(false);
			
			try
			{
				_mediaPlayer.stop();
			}
			catch (e:Error)
			{

			}
			if (_mediaElement)
			{
				if (_mediaContainer && _mediaContainer.containsMediaElement(_mediaElement))
				{
					_mediaContainer.removeMediaElement(_mediaElement);
				}
				_mediaElement=undefined;
			}
		}

		/**
		 * 播放时间改变
		 * @param evt
		 *
		 */
		private function _onCurrentTimeChange(evt:TimeEvent):void
		{
			var tTime:Number=0;
			if (!_mediaPlayer.duration)
			{
				tTime=duarationTime;
			}
			else
			{
				tTime=_mediaPlayer.duration;
			}
			tTime=duarationTime;
			var curTime:Number=evt.time+curPosTime;
			//if(evt.time)
			//trace("time:" +curTime+" duration: "+tTime);
			this.dispatchEvent(new PesiloEvent(PesiloEvent.VIDEO_TIME_UPDATE_EVENT, {"time": curTime, "duration": tTime}));
			//_updateProgressBar ( evt.time / _mediaPlayer.duration ) ;
		}

		private function _onCanLoadChange(evt:MediaPlayerCapabilityChangeEvent):void
		{
			trace("_onCanLoadChange () , evt.enabled : " + evt.enabled);
		}

		private function _onCanPlayChange(evt:MediaPlayerCapabilityChangeEvent):void
		{
			trace("_onCanPlayChange () , evt.enabled : " + evt.enabled);
		}

		private function _onCanSeekChange(evt:MediaPlayerCapabilityChangeEvent):void
		{
			trace("_onCanSeekChange () , evt.enabled : " + evt.enabled);
		}

		private function _onMediaError(evt:MediaErrorEvent):void
		{
			errorTime++;
			if(errorTime>10)return;
			trace("_onMediaError () , evt.error : " + evt.error);
			
			curPosTime=curPosTime+1;
			_playVideo(vo.url + "?start=" + curPosTime, vo.list);
			
			
		}

		/**
		 * 播放结束
		 * @param evt
		 *
		 */
		private function _onComplete(evt:TimeEvent):void
		{
			//trace ( "_onComplete () " ) ;
			isStop=true;
			this.dispatchEvent(new PesiloEvent(PesiloEvent.VIDEO_TIME_COMPLETE_EVENT));
			//_disableControls ( ) ;
			//cleanUpVideo ( ) ;
		}

		private function onMetaData(metadata:Object):void
		{
			errorTime=0;
			trace("Got metadata.");

			keyList=[];
			if (metadata)
			{

				if (metadata.seekpoints)
				{

					for (var i:uint=0; i < metadata["seekpoints"].length; i++)
					{
						var obj:Object={"time": metadata["seekpoints"][i]["time"], "pos": metadata["seekpoints"][i]["offset"]};
						keyList.push(obj);
					}
				}

				duarationTime=metadata.duration;
				trace(duarationTime)
			}
		}

		/**
		 * 播放状态改变
		 * @param evt
		 */
		private function _onMediaPlayerStateChange(evt:MediaPlayerStateChangeEvent):void
		{
			trace ( "          ************** _onMediaPlayerStateChange () , evt.state : " + evt.state ) ;
			this.dispatchEvent(new PesiloEvent(PesiloEvent.VIDEO_STATUS_CHANGE_EVENT,evt.state));
			switch (evt.state)
			{
				case MediaPlayerState.PLAYING:
					break;
				case MediaPlayerState.LOADING:
					break;
				case MediaPlayerState.BUFFERING:
					break;
				case MediaPlayerState.UNINITIALIZED:
					break;
				case MediaPlayerState.READY:
					if(!_mediaElement)return;
					if (isNewVideo)
					{
						isNewVideo=false;
						VideoElement(_mediaElement).client.addHandler("onMetaData", onMetaData);
					}
					var media:Metadata=_mediaElement.metadata
					this.dispatchEvent(new PesiloEvent(PesiloEvent.VIDEO_READY_EVENT));
					break;
				default:
					break;
			}
		}

	}

}